1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.math;
18
19 import static com.google.common.math.MathBenchmarking.ARRAY_MASK;
20 import static com.google.common.math.MathBenchmarking.ARRAY_SIZE;
21 import static com.google.common.math.MathBenchmarking.RANDOM_SOURCE;
22 import static com.google.common.math.MathBenchmarking.randomBigInteger;
23 import static com.google.common.math.MathBenchmarking.randomNonNegativeBigInteger;
24
25 import com.google.caliper.BeforeExperiment;
26 import com.google.caliper.Benchmark;
27 import com.google.caliper.Param;
28 import com.google.common.math.DoubleMath;
29 import com.google.common.math.IntMath;
30 import com.google.common.math.LongMath;
31
32
33
34
35
36
37
38
39 public class ApacheBenchmark {
40 private enum Impl {
41 GUAVA {
42 @Override
43 public double factorialDouble(int n) {
44 return DoubleMath.factorial(n);
45 }
46
47 @Override
48 public int gcdInt(int a, int b) {
49 return IntMath.gcd(a, b);
50 }
51
52 @Override
53 public long gcdLong(long a, long b) {
54 return LongMath.gcd(a, b);
55 }
56
57 @Override
58 public long binomialCoefficient(int n, int k) {
59 return LongMath.binomial(n, k);
60 }
61
62 @Override
63 public boolean noAddOverflow(int a, int b) {
64 try {
65 IntMath.checkedAdd(a, b);
66 return true;
67 } catch (ArithmeticException e) {
68 return false;
69 }
70 }
71
72 @Override
73 public boolean noAddOverflow(long a, long b) {
74 try {
75 LongMath.checkedAdd(a, b);
76 return true;
77 } catch (ArithmeticException e) {
78 return false;
79 }
80 }
81
82 @Override
83 public boolean noMulOverflow(int a, int b) {
84 try {
85 IntMath.checkedMultiply(a, b);
86 return true;
87 } catch (ArithmeticException e) {
88 return false;
89 }
90 }
91
92 @Override
93 public boolean noMulOverflow(long a, long b) {
94 try {
95 LongMath.checkedMultiply(a, b);
96 return true;
97 } catch (ArithmeticException e) {
98 return false;
99 }
100 }
101 };
102
103 public abstract double factorialDouble(int n);
104
105 public abstract long binomialCoefficient(int n, int k);
106
107 public abstract int gcdInt(int a, int b);
108
109 public abstract long gcdLong(long a, long b);
110
111 public abstract boolean noAddOverflow(int a, int b);
112
113 public abstract boolean noAddOverflow(long a, long b);
114
115 public abstract boolean noMulOverflow(int a, int b);
116
117 public abstract boolean noMulOverflow(long a, long b);
118 }
119
120 private final int[] factorials = new int[ARRAY_SIZE];
121 private final int[][] binomials = new int[ARRAY_SIZE][2];
122 private final int[][] nonnegInt = new int[ARRAY_SIZE][2];
123 private final long[][] nonnegLong = new long[ARRAY_SIZE][2];
124 private final int[][] intsToAdd = new int[ARRAY_SIZE][2];
125 private final int[][] intsToMul = new int[ARRAY_SIZE][2];
126 private final long[][] longsToAdd = new long[ARRAY_SIZE][2];
127 private final long[][] longsToMul = new long[ARRAY_SIZE][2];
128
129 @Param({"APACHE", "GUAVA"})
130 Impl impl;
131
132 @BeforeExperiment
133 void setUp() {
134 for (int i = 0; i < ARRAY_SIZE; i++) {
135 factorials[i] = RANDOM_SOURCE.nextInt(200);
136 for (int j = 0; j < 2; j++) {
137 nonnegInt[i][j] = randomNonNegativeBigInteger(Integer.SIZE - 2).intValue();
138 nonnegLong[i][j] = randomNonNegativeBigInteger(Long.SIZE - 2).longValue();
139 }
140 do {
141 for (int j = 0; j < 2; j++) {
142 intsToAdd[i][j] = randomBigInteger(Integer.SIZE - 2).intValue();
143 }
144 } while (!Impl.GUAVA.noAddOverflow(intsToAdd[i][0], intsToAdd[i][1]));
145 do {
146 for (int j = 0; j < 2; j++) {
147 longsToAdd[i][j] = randomBigInteger(Long.SIZE - 2).longValue();
148 }
149 } while (!Impl.GUAVA.noAddOverflow(longsToAdd[i][0], longsToAdd[i][1]));
150 do {
151 for (int j = 0; j < 2; j++) {
152 intsToMul[i][j] = randomBigInteger(Integer.SIZE - 2).intValue();
153 }
154 } while (!Impl.GUAVA.noMulOverflow(intsToMul[i][0], intsToMul[i][1]));
155 do {
156 for (int j = 0; j < 2; j++) {
157 longsToMul[i][j] = randomBigInteger(Long.SIZE - 2).longValue();
158 }
159 } while (!Impl.GUAVA.noMulOverflow(longsToMul[i][0], longsToMul[i][1]));
160
161 int k = binomials[i][1] = RANDOM_SOURCE.nextInt(MathBenchmarking.biggestBinomials.length);
162 binomials[i][0] = RANDOM_SOURCE.nextInt(MathBenchmarking.biggestBinomials[k] - k) + k;
163 }
164 }
165
166 @Benchmark long factorialDouble(int reps) {
167 long tmp = 0;
168 for (int i = 0; i < reps; i++) {
169 int j = i & ARRAY_MASK;
170 tmp += Double.doubleToRawLongBits(impl.factorialDouble(factorials[j]));
171 }
172 return tmp;
173 }
174
175 @Benchmark int intGCD(int reps) {
176 int tmp = 0;
177 for (int i = 0; i < reps; i++) {
178 int j = i & ARRAY_MASK;
179 tmp += impl.gcdInt(nonnegInt[j][0], nonnegInt[j][1]);
180 }
181 return tmp;
182 }
183
184 @Benchmark long longGCD(int reps) {
185 long tmp = 0;
186 for (int i = 0; i < reps; i++) {
187 int j = i & ARRAY_MASK;
188 tmp += impl.gcdLong(nonnegLong[j][0], nonnegLong[j][1]);
189 }
190 return tmp;
191 }
192
193 @Benchmark long binomialCoefficient(int reps) {
194 long tmp = 0;
195 for (int i = 0; i < reps; i++) {
196 int j = i & ARRAY_MASK;
197 tmp += impl.binomialCoefficient(binomials[j][0], binomials[j][1]);
198 }
199 return tmp;
200 }
201
202 @Benchmark int intAddOverflow(int reps) {
203 int tmp = 0;
204 for (int i = 0; i < reps; i++) {
205 int j = i & ARRAY_MASK;
206 if (impl.noAddOverflow(intsToAdd[j][0], intsToAdd[j][1])) {
207 tmp++;
208 }
209 }
210 return tmp;
211 }
212
213 @Benchmark int longAddOverflow(int reps) {
214 int tmp = 0;
215 for (int i = 0; i < reps; i++) {
216 int j = i & ARRAY_MASK;
217 if (impl.noAddOverflow(longsToAdd[j][0], longsToAdd[j][1])) {
218 tmp++;
219 }
220 }
221 return tmp;
222 }
223
224 @Benchmark int intMulOverflow(int reps) {
225 int tmp = 0;
226 for (int i = 0; i < reps; i++) {
227 int j = i & ARRAY_MASK;
228 if (impl.noMulOverflow(intsToMul[j][0], intsToMul[j][1])) {
229 tmp++;
230 }
231 }
232 return tmp;
233 }
234
235 @Benchmark int longMulOverflow(int reps) {
236 int tmp = 0;
237 for (int i = 0; i < reps; i++) {
238 int j = i & ARRAY_MASK;
239 if (impl.noMulOverflow(longsToMul[j][0], longsToMul[j][1])) {
240 tmp++;
241 }
242 }
243 return tmp;
244 }
245 }